﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;

namespace Anytao.Utils.Type
{
    /// <summary>
    /// A convert util class for parsing value type into reference type
    /// </summary>
    public static class ConvertHelper
    {
        public static T Parse<T>(string value) where T : struct
        {
            if (string.IsNullOrEmpty(value))
            {
                return default(T);
            }

            TypeConverter converter = TypeDescriptor.GetConverter(typeof(T));

            if (converter != null)
            {
                try
                {
                    return (T)converter.ConvertFromString(value);
                }
                catch
                {
                    return default(T);
                }
            }

            return default(T);
        }

        public static T Parse<T>(string value, T defaultValue) where T : struct
        {
            if (string.IsNullOrEmpty(value))
            {
                return defaultValue;
            }

            return default(T);
        }

        public static T Parse<T>(object o) where T : struct
        {
            return Parse<T>(o.ToString());
        }

        public static T? TryParse<T>(string value) where T : struct
        {
            if (string.IsNullOrEmpty(value))
            {
                return null;
            }

            TypeConverter converter = TypeDescriptor.GetConverter(typeof(T));

            if (converter != null)
            {
                try
                {
                    return (T)converter.ConvertFromString(value);
                }
                catch
                {
                    return null;
                }
            }

            return null;
        }

        public static T? TryParse<T>(object o) where T : struct
        {
            return TryParse<T>(o.ToString());
        }

        public static T Parse<T>(string value, Func<T> defaultSelector)
        {
            if (string.IsNullOrEmpty(value))
            {
                return defaultSelector();
            }

            //todo: 01, {anytao}, to implement the converter
            TypeConverter converter = TypeDescriptor.GetConverter(typeof(T));

            if (converter != null)
            {
                try
                {
                    return (T)converter.ConvertFromString(value);
                }
                catch
                {
                    return default(T);
                }
            }

            return default(T);
        }
    }
   
    public class Program
    {
        public static void Main()
        {
            int i = ConvertHelper.Parse<int>("100", () => -20);
        }
    }
}
